package killerqueen.game.xml.loader;

import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.Unmarshaller;

import killerqueen.game.xml.generated.Level;
import killerqueen.game.xml.generated.ObjectFactory;

/**
 * @author Demián Gutierrez
 */
public class LevelLoader {

  private static final String COM_SUN_XML_BIND_OBJECT_FACTORY = //
  "com.sun.xml.bind.ObjectFactory";
  private static final String COM_SUN_XML_INTERNAL_BIND_OBJECT_FACTORY = //
  "com.sun.xml.internal.bind.ObjectFactory";

  // --------------------------------------------------------------------------------
  // Load/Save a Level
  // --------------------------------------------------------------------------------

  public Level load(InputStream is) throws Exception {
    JAXBContext jc = JAXBContext.newInstance( //
        ObjectFactory.class.getPackage().getName());

    Unmarshaller unmarshaller = jc.createUnmarshaller();
    setObjectFactory(unmarshaller);

    Level xmlLevel = (Level) unmarshaller.unmarshal(is);

    return xmlLevel;
  }

  // --------------------------------------------------------------------------------

  public void save(OutputStream os, Level level) throws Exception {
    JAXBContext jc = JAXBContext.newInstance( //
        ObjectFactory.class.getPackage().getName());

    Marshaller marshaller = jc.createMarshaller();

    marshaller.marshal(level, os);
  }

  // --------------------------------------------------------------------------------
  // Check http://java.net/projects/jaxb/lists/users/archive/2008-07/message/75
  // --------------------------------------------------------------------------------

  private void setObjectFactory(Unmarshaller unmarshaller) //
      throws PropertyException {

    try {
      unmarshaller.setProperty(COM_SUN_XML_BIND_OBJECT_FACTORY, //
          new ObjectFactory());
    } catch (PropertyException e) {
      unmarshaller.setProperty(COM_SUN_XML_INTERNAL_BIND_OBJECT_FACTORY, //
          new ObjectFactory());
    }
  }
}
